/*
 * File Name:               ColorExtension.cs
 * 
 * Description:             普通类
 * Author:                  lisiyu <576603306@qq.com>
 * Create Date:             2017/02/28
 */

using System;
using UnityEngine;

public static class ColorExtension
{
    //#region RGB和HSB的转换推算
    //// 参考blog http://www.cnblogs.com/wang726zq/p/3660581.html
    //// h [0, 360] s[0,1] b[0,1]
    //public static float[] hsb2rgb(float[] hsb)
    //{
    //    float[] rgb = new float[3];
    //    //先令饱和度和亮度为100%，调节色相h
    //    for (int offset = 240, i = 0; i < 3; i++, offset -= 120)
    //    {
    //        //算出色相h的值和三个区域中心点(即0°，120°和240°)相差多少，然后根据坐标图按分段函数算出rgb。但因为色环展开后，红色区域的中心点是0°同时也是360°，不好算，索性将三个区域的中心点都向右平移到240°再计算比较方便
    //        float x = Math.Abs((hsb[0] + offset) % 360 - 240);
    //        //如果相差小于60°则为255
    //        if (x <= 60) rgb[i] = 255;
    //        //如果相差在60°和120°之间，
    //        else if (60 < x && x < 120) rgb[i] = ((1 - (x - 60) / 60) * 255);
    //        //如果相差大于120°则为0
    //        else rgb[i] = 0;
    //    }
    //    //在调节饱和度s
    //    for (int i = 0; i < 3; i++)
    //        rgb[i] += (255 - rgb[i]) * (1 - hsb[1]);
    //    //最后调节亮度b
    //    for (int i = 0; i < 3; i++)
    //        rgb[i] *= hsb[2];
    //    return rgb;
    //}

    //// 值域均为 [0, 255]
    //public static float[] rgb2hsb(float[] rgb)
    //{
    //    float[] hsb = new float[3];
    //    float[] rearranged = new float[3];
    //    Array.Copy(rgb, rearranged, rgb.Length);//  rgb.clone();
    //    int maxIndex = 0, minIndex = 0;
    //    float tmp;
    //    //将rgb的值从小到大排列，存在rearranged数组里
    //    for (int i = 0; i < 2; i++)
    //    {
    //        for (int j = 0; j < 2 - i; j++)
    //            if (rearranged[j] > rearranged[j + 1])
    //            {
    //                tmp = rearranged[j + 1];
    //                rearranged[j + 1] = rearranged[j];
    //                rearranged[j] = tmp;
    //            }
    //    }
    //    //rgb的下标分别为0、1、2，maxIndex和minIndex用于存储rgb中最大最小值的下标
    //    for (int i = 0; i < 3; i++)
    //    {
    //        if (rearranged[0] == rgb[i]) minIndex = i;
    //        if (rearranged[2] == rgb[i]) maxIndex = i;
    //    }
    //    //算出亮度
    //    hsb[2] = rearranged[2] / 255.0f;
    //    //算出饱和度
    //    hsb[1] = 1 - rearranged[0] / rearranged[2];
    //    //算出色相
    //    if (hsb[1] == 0f || hsb[2] == 0f)
    //        hsb[0] = 0f;
    //    else
    //        hsb[0] = maxIndex * 120 + 60 * (rearranged[1] / hsb[1] / rearranged[2] + (1 - 1 / hsb[1])) * ((maxIndex - minIndex + 3) % 3 == 1 ? 1 : -1);
    //    //防止色相为负值
    //    hsb[0] = (hsb[0] + 360) % 360;
    //    return hsb;
    //}
    //#endregion RGB和HSB的转换推算

    //public static Color hsb2color(float[] hsb)
    //{
    //    return rgb2color(hsb2rgb(hsb));
    //}


    public static Color rgb2color(int r, int g, int b)
    {
        var ret = new Color(r / 255f, g / 255f, b / 255f);
        return ret;
    }

    public static Texture2D getHTexture2D(int width, int height)
    {
        var ret = new Texture2D(width, height);

        var colors = ret.GetPixels();
        Color _tmpColor;
        for (int i = 0; i < height; i++)
        {
            var h = 360f * i / (height - 1);
            _tmpColor = Color.HSVToRGB(h, 1, 1);
            for (int j = 0; j < width; j++)
            {
                colors[width * i + j] = _tmpColor;
            }
        }
        ret.SetPixels(colors);
        ret.Apply();
        return ret;
    }

    public static Color random()
    {
        // h[0, 360] s[0, 1] b[0, 1]
        var h = UnityEngine.Random.Range(0f, 360f);
        var s = UnityEngine.Random.Range(0f, 1f);
        var v = UnityEngine.Random.Range(0f, 1f);

        return Color.HSVToRGB(h, s, v);
    }


    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    public static Color ParseColor(string text)
    {
        if (text.Length == 6)
            return ParseColor24(text);
        else if (text.Length == 8)
            return ParseColor32(text);
        else
            return Color.white;
    }

    /// <summary>
    /// Parse a RrGgBb color encoded in the string.
    /// </summary>

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    public static Color ParseColor24(string text)
    {
        int r = (HexToDecimal(text[0]) << 4) | HexToDecimal(text[1]);
        int g = (HexToDecimal(text[2]) << 4) | HexToDecimal(text[3]);
        int b = (HexToDecimal(text[4]) << 4) | HexToDecimal(text[5]);
        float f = 1f / 255f;
        return new Color(f * r, f * g, f * b, 1f);
    }

    /// <summary>
    /// Parse a RrGgBbAa color encoded in the string.
    /// </summary>

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    public static Color ParseColor32(string text)
    {
        int r = (HexToDecimal(text[0]) << 4) | HexToDecimal(text[1]);
        int g = (HexToDecimal(text[2]) << 4) | HexToDecimal(text[3]);
        int b = (HexToDecimal(text[4]) << 4) | HexToDecimal(text[5]);
        int a = (HexToDecimal(text[6]) << 4) | HexToDecimal(text[7]);
        float f = 1f / 255f;
        return new Color(f * r, f * g, f * b, f * a);
    }

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    public static int HexToDecimal(char ch)
    {
        switch (ch)
        {
            case '0': return 0x0;
            case '1': return 0x1;
            case '2': return 0x2;
            case '3': return 0x3;
            case '4': return 0x4;
            case '5': return 0x5;
            case '6': return 0x6;
            case '7': return 0x7;
            case '8': return 0x8;
            case '9': return 0x9;
            case 'a':
            case 'A': return 0xA;
            case 'b':
            case 'B': return 0xB;
            case 'c':
            case 'C': return 0xC;
            case 'd':
            case 'D': return 0xD;
            case 'e':
            case 'E': return 0xE;
            case 'f':
            case 'F': return 0xF;
        }
        return 0xF;
    }


    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    static public string EncodeColor(Color c) { return EncodeColor24(c); }


    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    static public string EncodeColor24(Color c)
    {
        int i = 0xFFFFFF & (ColorToInt(c) >> 8);
        return DecimalToHex24(i);
    }

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    static public string EncodeColor32(Color c)
    {
        int i = ColorToInt(c);
        return i.ToString("X6");
    }

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    static public int ColorToInt(Color c)
    {
        int retVal = 0;
        retVal |= Mathf.RoundToInt(c.r * 255f) << 24;
        retVal |= Mathf.RoundToInt(c.g * 255f) << 16;
        retVal |= Mathf.RoundToInt(c.b * 255f) << 8;
        retVal |= Mathf.RoundToInt(c.a * 255f);
        return retVal;
    }

    [System.Diagnostics.DebuggerHidden]
    [System.Diagnostics.DebuggerStepThrough]
    static public string DecimalToHex24(int num)
    {
        num &= 0xFFFFFF;
        return num.ToString("X6");
    }

}
